/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package algoritmos_busqueda;

/**
 *
 * @author stbn
 */
import java.util.List;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import java.io.Serializable;
public class Mapa implements Serializable {
    
    private Cuadrado tablero [][];
    private int amplitud;


    public Mapa(int amp)
    {
        tablero = new Cuadrado[amp][amp];
        amplitud = amp;
    }

    public boolean esOrigen(int x, int y)
    {
        return tablero[x][y].esOrigen();
    }

    public boolean esDestino(int x, int y)
    {
        return tablero[x][y].esDestino();
    }

    public Cuadrado obtenerorigen()
    {
        Cuadrado orig = null;
        for (int a = 0; a < amplitud ;a++ )
        {
            for (int b = 0; b < amplitud ;b++ )
            {
                if (esOrigen(b,a)) orig = obtenercuadrado(b,a);
            }
        }
        //JOptionPane.showMessageDialog(null, String.format("el origen esta en la posicion %d %d", orig.obtenerx(), orig.obtenery()));
        return orig;
    }

    public Cuadrado obtenerDestino()
    {
        Cuadrado dest = null;
        for (int a = 0; a < amplitud ;a++ )
        {
            for (int b = 0; b < amplitud ;b++ )
            {
                if (esDestino(b,a)) dest = obtenercuadrado(b,a);
            }
        }
        //JOptionPane.showMessageDialog(null, String.format("el origen esta en la posicion %d %d", orig.obtenerx(), orig.obtenery()));
        return dest;
    }


    public void metercuadrado(Cuadrado c)
    {
        tablero[c.obtenerx()][c.obtenery()] = c;
    }

    public Cuadrado obtenercuadrado(int x, int y)
    {
        return tablero[x][y];
    }

    public List obtenervecinos(Cuadrado c)
    {
        int borde = amplitud - 1;
        // hay nueve casos: esquinas, bordes, y el caso comun.
        // con las sentencias if no agregara obstaculos
        List<Cuadrado> vecinos = new ArrayList<Cuadrado>();
        if (c.obtenerx() == 0)
        {

         /////////////////////////

        if (c.obtenery() == 0)
        {
            if (!obtenercuadrado(1,0).esobstaculo()) vecinos.add(obtenercuadrado(1,0));
            if (!obtenercuadrado(0,1).esobstaculo()) vecinos.add(obtenercuadrado(0,1));
        }
        else if (c.obtenery() == borde)
        {
            if (!obtenercuadrado(1, borde).esobstaculo()) vecinos.add(obtenercuadrado(1, borde));
            if (!obtenercuadrado(0, borde -1).esobstaculo()) vecinos.add(obtenercuadrado(0, borde -1));
        }
        else
        {
            if (!obtenercuadrado(0, c.obtenery() + 1).esobstaculo()) vecinos.add(obtenercuadrado(0,c.obtenery()+1));
            if (!obtenercuadrado(0, c.obtenery() - 1).esobstaculo()) vecinos.add(obtenercuadrado(0,c.obtenery()-1));
            if (!obtenercuadrado(1, c.obtenery()).esobstaculo()) vecinos.add(obtenercuadrado(1,c.obtenery()));
        }

        ///////////////////////////

        }
        else if (c.obtenerx() == borde)
        {


         /////////////////////////

        if (c.obtenery() == 0)
        {
            if (!obtenercuadrado(borde - 1, 0).esobstaculo()) vecinos.add(obtenercuadrado(borde - 1, 0));
            if (!obtenercuadrado(borde, 1).esobstaculo()) vecinos.add(obtenercuadrado(borde,1));
        }
        else if (c.obtenery() == borde)
        {
            if (!obtenercuadrado(borde - 1, borde).esobstaculo()) vecinos.add(obtenercuadrado(borde - 1, borde));
            if (!obtenercuadrado(borde, borde - 1).esobstaculo()) vecinos.add(obtenercuadrado(borde , borde - 1));
        }
        else
        {
            if (!obtenercuadrado(borde, c.obtenery() + 1).esobstaculo()) vecinos.add(obtenercuadrado(borde, c.obtenery()+1));
            if (!obtenercuadrado(borde, c.obtenery() - 1).esobstaculo()) vecinos.add(obtenercuadrado(borde, c.obtenery()-1));
            if (!obtenercuadrado(borde - 1, c.obtenery()).esobstaculo()) vecinos.add(obtenercuadrado(borde - 1, c.obtenery()));
        }

        ///////////////////////////




        }
        else
        {



         /////////////////////////

        if (c.obtenery() == 0)
        {
            if (!obtenercuadrado(c.obtenerx() + 1, 0).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() + 1, 0));
            if (!obtenercuadrado(c.obtenerx() - 1, 0).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() - 1, 0));
            if (!obtenercuadrado(c.obtenerx(), 1).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx(), 1));
        }
        else if (c.obtenery() == borde)
        {
            if (!obtenercuadrado(c.obtenerx() + 1, borde).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() + 1, borde));
            if (!obtenercuadrado(c.obtenerx() - 1, borde).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() - 1, borde));
            if (!obtenercuadrado(c.obtenerx(), borde - 1).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx(), borde - 1));
        }
        else
        {
            if (!obtenercuadrado(c.obtenerx() + 1, c.obtenery()).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() + 1, c.obtenery()));
            if (!obtenercuadrado(c.obtenerx() - 1, c.obtenery()).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx() - 1, c.obtenery()));
            if (!obtenercuadrado(c.obtenerx(), c.obtenery() + 1).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx(), c.obtenery() + 1));
            if (!obtenercuadrado(c.obtenerx(), c.obtenery() - 1).esobstaculo()) vecinos.add(obtenercuadrado(c.obtenerx(), c.obtenery() - 1));
        }

        ///////////////////////////


        }

        return vecinos;

    }

    public void limpiar()
    {
        for (int a = 0; a < amplitud ;a++ )
        {
            for (int b = 0; b < amplitud ;b++ )
            {
                obtenercuadrado(b,a).limpiar();
            }
        }
    }


    public int obtenerDistanciaManhatan(Cuadrado c)
    {
        Cuadrado destino = obtenerDestino();
        return Math.abs(c.obtenerx() - destino.obtenerx()) + Math.abs(c.obtenery() - destino.obtenery());
    }

    public int obtenerBDistanciaManhatan(Cuadrado c)
    {
        Cuadrado origen = this.obtenerorigen();
        return Math.abs(c.obtenerx() - origen.obtenerx()) + Math.abs(c.obtenery() - origen.obtenery());
    }

    public void actualizarPropiedades(Cuadrado actualizador, Cuadrado actualizado)
    {
        if (actualizador.esCamino()) actualizado.asignarcamino();
        if (actualizador.esobstaculo()) actualizado.asignarobstaculo();
        if (actualizador.esDestino()) actualizado.asignardestino();
        if (actualizador.esOrigen()) actualizado.asignarorigen();
        actualizado.actualizarIcono(actualizador);
    }

    

}
